{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 参数化量子线路\n",
    "\n",
    "`Linux` `CPU` `全流程` `初级` `中级` `高级`\n",
    "\n",
    "[![](https://gitee.com/mindspore/docs/raw/master/resource/_static/logo_source.png)](https://gitee.com/mindspore/docs/blob/master/docs/mindquantum/docs/source_zh_cn/parameterized_quantum_circuit.ipynb) [![](https://gitee.com/mindspore/mindquantum/raw/master/tutorials/images/view_mindquantum_api.png)](https://mindspore.cn/mindquantum/api/zh-CN/master/index.html)\n",
    "\n",
    "## 1. 概述\n",
    "\n",
    "参数化量子线路（Parameterized Quantum Circuit, PQC）即由含参数的量子门组成的量子线路，是进行量子机器学习的途径之一。在很多情况下，为了能与经典机器学习中神经网络进行类比，我们也经常会把参数化量子线路称为量子神经网络。量子-经典混合计算架构MindQuantum能够处理此类参数化量子线路，并利用量子神经网络的可逆性对该线路进行自动微分，最后通过测量得到的观测值，即可计算出观测值对于各参数的导数。\n",
    "\n",
    "构建PQC并用PQC模拟器算子对量子线路进行演化的大致流程如下：\n",
    "\n",
    "- Step 1 初始化量子线路；\n",
    "- Step 2 在量子线路中加入所需的含参量子门或者不含参量子门；\n",
    "- Step 3 利用PQC模拟器算子进行态演化或者梯度求解。\n",
    "\n",
    "## 2. 环境准备\n",
    "\n",
    "导入本教程所依赖的模块。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np                                    #导入numpy库并简写为np\n",
    "import mindquantum as mq                              #导入mindquantum库并简写为mq\n",
    "from mindquantum.gate import X, Y, Z, H, RX, RY, RZ   #导入量子门H, X, Y, Z, RX, RY, RZ"
   ]
  },
  {
   "source": [
    "说明：\n",
    "\n",
    "（1）numpy是一个功能强大的Python库，主要用于对多维数组执行计算，支持大量的维度数组与矩阵运算，此外也针对数组运算提供大量的数学函数库；\n",
    "\n",
    "（2）mindquantum是量子-经典混合计算框架，支持多种量子神经网络的训练和推理；\n",
    "\n",
    "（3）搭建的量子线路中所需执行的量子门需要从mindquantum.gate模块中导入；\n",
    "\n",
    "## 3. 量子门\n",
    "\n",
    "量子门（量子逻辑门）是对量子比特进行操作的基本逻辑单元，是量子线路的基础。对于经典电路来说，任意的逻辑电路都可以由一系列基本逻辑门构成，类似地，任意的量子线路也可以由一系列基本量子门构成，如单量子比特门和受控非门。常用的基本量子门有`X`门、`Y`门、`Z`门、`Hadamard`门（`H`门）、`CNOT`门以及旋转门`RX`门、`RY`门和`RZ`门。\n",
    "\n",
    "一般来说，量子门可以分为含参量子门和不含参量子门。例如，不含参的量子门有`X`门、`Y`门、`Z`门、`Hadamard`门（`H`门）和`CNOT`门，它们的矩阵形式分别如下：\n",
    "\n",
    "$$\\text{X}=\\begin{pmatrix}0&1\\\\\\\\1&0\\end{pmatrix},\\text{Y}=\\begin{pmatrix}0&-i\\\\\\\\i&0\\end{pmatrix},\\text{Z}=\\begin{pmatrix}1&0\\\\\\\\0&-1\\end{pmatrix},\\text{H}=\\frac{1}{\\sqrt{2}}\\begin{pmatrix}1&1\\\\\\\\1&-1\\end{pmatrix},\\text{CNOT}=\\begin{pmatrix}1&0&0&0\\\\\\\\0&1&0&0\\\\\\\\0&0&0&1\\\\\\\\0&0&1&0\\end{pmatrix}.$$\n",
    "\n",
    "分别打印上述量子门的矩阵形式，可以得到：\n"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Gate name: X\n"
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[0, 1],\n       [1, 0]])"
     },
     "metadata": {},
     "execution_count": 2
    }
   ],
   "source": [
    "print('Gate name:', X)\n",
    "X.matrix()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Gate name: Y\n"
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[ 0.+0.j, -0.-1.j],\n       [ 0.+1.j,  0.+0.j]])"
     },
     "metadata": {},
     "execution_count": 3
    }
   ],
   "source": [
    "print('Gate name:', Y)\n",
    "Y.matrix()"
   ]
  },
  {
   "source": [
    "说明：矩阵里的每一项，左边的“0.”表示小数形式（浮点数）的实部（若实部为负，则在小数前显示“-”，否则默认为非负），右边的“0.”表示小数形式（浮点数）的虚部（若虚部为负，则在小数前会显示“-”，否则显示“+”），j表示虚数单位$i$）。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Gate name: Z\n"
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[ 1,  0],\n       [ 0, -1]])"
     },
     "metadata": {},
     "execution_count": 4
    }
   ],
   "source": [
    "print('Gate name:', Z)\n",
    "Z.matrix()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Gate name: H\n"
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[ 0.70710678,  0.70710678],\n       [ 0.70710678, -0.70710678]])"
     },
     "metadata": {},
     "execution_count": 5
    }
   ],
   "source": [
    "print('Gate name:', H)\n",
    "H.matrix()"
   ]
  },
  {
   "source": [
    "对于`CNOT`门，其本质上是受控`X`门（`Controlled-X` gate），因此在MindQuantum中，如果我们需要执行`CNOT`门，只需设定`X`门的控制比特位和目标比特位即可（实际上，任意的量子门我们都可以设定控制比特位和所需执行量子门操作的目标比特位）。例如："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "X(0 <-: 1)\n"
    }
   ],
   "source": [
    "cnot = X.on(0, 1)   #X门作用在第0位量子比特且受第1位量子比特控制\n",
    "print(cnot)"
   ]
  },
  {
   "source": [
    "说明：\n",
    "\n",
    "（1）X(0 <-: 1) ，表示第0位量子比特位为目标比特位，第1位量子比特位为控制比特位，第0位量子比特受第1位量子比特控制，若第1位量子比特为1，则对第0位量子比特执行`X`门操作，否则不作任何操作；\n",
    "\n",
    "上面介绍了一些常用的不含参量子门，接下来，我们将介绍一些含参量子门（如旋转门`RX`门、`RY`门和`RZ`门），通过赋予旋转角度$\\theta$某些确定的值，可以得到作用不同的旋转门。另外，这些含参量子门是后续搭建量子神经网络的重要组成单元。\n",
    "\n",
    "例如，`RX`门、`RY`门和`RZ`门的矩阵形式如下：\n",
    "\n",
    "$$\\text{RX}(\\theta)= e^{-\\frac{i\\theta X}{2}}=\\cos\\left(\\frac{\\theta}{2}\\right)\\cdot I-i\\sin\\left(\\frac{\\theta}{2}\\right)\\cdot X=\\begin{pmatrix}\\cos\\left(\\frac{\\theta}{2}\\right)&-i\\sin\\left(\\frac{\\theta}{2}\\right)\\\\\\\\-i\\sin\\left(\\frac{\\theta}{2}\\right)&\\cos\\left(\\frac{\\theta}{2}\\right)\\end{pmatrix},$$\n",
    "\n",
    "$$\\text{RY}(\\theta)= e^{-\\frac{i\\theta Y}{2}}=\\cos\\left(\\frac{\\theta}{2}\\right)\\cdot I-i\\sin\\left(\\frac{\\theta}{2}\\right)\\cdot Y=\\begin{pmatrix}\\cos\\left(\\frac{\\theta}{2}\\right)&-\\sin\\left(\\frac{\\theta}{2}\\right)\\\\\\\\-\\sin\\left(\\frac{\\theta}{2}\\right)&\\cos\\left(\\frac{\\theta}{2}\\right)\\end{pmatrix},$$\n",
    "\n",
    "$$\\text{RZ}(\\theta)= e^{-\\frac{i\\theta Z}{2}}=\\cos\\left(\\frac{\\theta}{2}\\right)\\cdot I-i\\sin\\left(\\frac{\\theta}{2}\\right)\\cdot Z=\\begin{pmatrix}e^{-\\frac{i\\theta}{2}}&0\\\\\\\\0&e^{\\frac{i\\theta}{2}}\\end{pmatrix}.$$\n",
    "\n",
    "我们令$\\theta$分别为$0、\\frac{\\pi}{2}$和$\\pi$，然后打印$\\text{RX}(0)$门、$\\text{RY}(\\frac{\\pi}{2}$)门和$\\text{RZ}(\\pi)$门的矩阵形式，可以得到："
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Gate name: RX(theta)\n"
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[1.+0.j, 0.-0.j],\n       [0.-0.j, 1.+0.j]])"
     },
     "metadata": {},
     "execution_count": 7
    }
   ],
   "source": [
    "rx = RX('theta')\n",
    "print('Gate name:', rx)\n",
    "rx.matrix({'theta': 0})   #赋予theta的值为0"
   ]
  },
  {
   "source": [
    "当$\\theta=0$时，此时$\\text{RX}(0)$门就是我们熟悉的`I`门。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Gate name: RY(theta)\n"
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[ 0.70710678, -0.70710678],\n       [ 0.70710678,  0.70710678]])"
     },
     "metadata": {},
     "execution_count": 8
    }
   ],
   "source": [
    "ry = RY('theta')\n",
    "print('Gate name:', ry)\n",
    "ry.matrix({'theta': np.pi/2})   #pi需要从np中导入，赋予theta的值为pi/2"
   ]
  },
  {
   "source": [
    "当$\\theta=\\frac{\\pi}{2}$时，此时$\\text{RY}(\\frac{\\pi}{2})$门就是我们熟悉的`H`门。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "Gate name: RZ(theta)\n"
    },
    {
     "output_type": "execute_result",
     "data": {
      "text/plain": "array([[0.-1.j, 0.+0.j],\n       [0.+0.j, 0.+1.j]])"
     },
     "metadata": {},
     "execution_count": 9
    }
   ],
   "source": [
    "rz = RZ('theta')\n",
    "print('Gate name:', rz)\n",
    "np.round(rz.matrix({'theta': np.pi}))   #赋予theta的值为pi，由于计算机中存在浮点数不精确的问题，因此通过函数np.round返回浮点数的四舍五入值。"
   ]
  },
  {
   "source": [
    "当$\\theta=\\pi$时，此时$\\text{RZ}(\\pi)$门就是我们熟悉的`Z`门。（相差一个全局相位$-i$）\n",
    "\n",
    "## 4. 量子线路\n",
    "\n",
    "量子线路（也称量子逻辑电路）是最常用的通用量子计算模型，表示在抽象概念下，对于量子比特进行操作的线路。类比于经典线路，我们可以把一系列的量子逻辑门进行精心的设计组合，构成一个量子线路并完成一定的任务。例如，我们构建如下图所示的量子线路，该量子线路由三个量子门构成，分别是作用在$q_0$比特上的`H`门，作用在$q_0$和$q_1$比特上的`CNOT`门（即作用在$q_1$比特上且受$q_0$比特控制的`X`门）和作用在$q_2$比特上的$\\text{RY}(\\theta)$门。\n",
    "\n",
    "![quantum circuit](https://gitee.com/mindspore/docs/raw/master/docs/mindquantum/docs/source_zh_cn/images/quantum_circuit.png)\n",
    "\n",
    "通过在量子线路中添加作用在不同量子比特位上的量子门即可快速完成对量子线路的搭建。"
   ],
   "cell_type": "markdown",
   "metadata": {}
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "tags": []
   },
   "outputs": [
    {
     "output_type": "stream",
     "name": "stdout",
     "text": "H(0)\nX(1 <-: 0)\nRY(theta|2)\n=========Circuit Summary=========\n|Total number of gates  : 3.    |\n|Parameter gates        : 1.    |\n|with 1 parameters are  : theta.|\n|Number qubit of circuit: 3     |\n=================================\n"
    }
   ],
   "source": [
    "from mindquantum import Circuit     #导入Circuit模块，用于搭建量子线路\n",
    "\n",
    "encoder = Circuit()                 #初始化量子线路\n",
    "encoder += H.on(0)                  #H门作用在第0位量子比特\n",
    "encoder += X.on(1,0)                #X门作用在第1位量子比特且受第0位量子比特控制\n",
    "encoder += RY('theta').on(2)        #RY(theta)门作用在第2位量子比特\n",
    "\n",
    "print(encoder)                      #打印Encoder\n",
    "encoder.summary()                   #总结Encoder量子线路"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "从对Encoder的Summary中可以看到，该量子线路由3个量子门组成，其中有1个含参量子门且参数为theta，该量子线路调控的量子比特数为3。\n",
    "\n",
    "因此，我们可以根据自身所需求解的问题，搭建对应的量子线路。赶紧动手搭建属于你的第一个量子线路吧！\n",
    "\n",
    "若想查询更多关于MindQuantum的API，请点击：[https://mindspore.cn/mindquantum/](https://mindspore.cn/mindquantum/)。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3.7.5 64-bit",
   "language": "python",
   "name": "python37564bit6afae4a42a5941c0967cdcfc2650559a"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5-final"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}